const { Connection, Keypair, Transaction, sendAndConfirmTransaction, PublicKey, SystemProgram } = require('@solana/web3.js');
const { Program, AnchorProvider, Wallet } = require('@coral-xyz/anchor');
const fs = require('fs');
const path = require('path');

const DEVNET_RPC = 'https://api.devnet.solana.com';
const PROGRAM_ID = '5MZg21QLaQjQi7Gv5YmcguZJHd1NB8itwXznagCbuLk7';

async function initializeFactory() {
  console.log('🏭 初始化工厂合约...');
  
  const connection = new Connection(DEVNET_RPC, 'confirmed');
  
  // 生成或加载授权钱包
  let authorityKeypair;
  
  // 先尝试使用现有的测试钱包
  const testWalletPath = path.join(__dirname, '..', 'test-wallet-1754098590485.json');
  const authorityWalletPath = path.join(__dirname, '..', 'factory-authority.json');
  
  try {
    if (fs.existsSync(testWalletPath)) {
      const walletData = JSON.parse(fs.readFileSync(testWalletPath, 'utf8'));
      authorityKeypair = Keypair.fromSecretKey(new Uint8Array(walletData.secretKey));
      console.log(`✅ 使用现有测试钱包作为授权钱包: ${authorityKeypair.publicKey.toString()}`);
    } else if (fs.existsSync(authorityWalletPath)) {
      const walletData = JSON.parse(fs.readFileSync(authorityWalletPath, 'utf8'));
      authorityKeypair = Keypair.fromSecretKey(new Uint8Array(walletData.secretKey));
      console.log(`✅ 加载现有授权钱包: ${authorityKeypair.publicKey.toString()}`);
    } else {
      authorityKeypair = Keypair.generate();
      // 保存钱包
      fs.writeFileSync(authorityWalletPath, JSON.stringify({
        publicKey: authorityKeypair.publicKey.toString(),
        secretKey: Array.from(authorityKeypair.secretKey)
      }, null, 2));
      console.log(`✅ 生成新的授权钱包: ${authorityKeypair.publicKey.toString()}`);
    }
  } catch (error) {
    console.log('❌ 处理授权钱包失败:', error.message);
    return;
  }
  
  // 检查账户余额
  const balance = await connection.getBalance(authorityKeypair.publicKey);
  console.log(`💰 授权账户余额: ${balance / 1e9} SOL`);
  
  if (balance < 0.01 * 1e9) {
    console.log('❌ 余额不足，请向账户充值 SOL');
    console.log(`请向以下地址充值: ${authorityKeypair.publicKey.toString()}`);
    return;
  }
  
  try {
    // 设置 Anchor provider
    const provider = new AnchorProvider(
      connection,
      new Wallet(authorityKeypair),
      AnchorProvider.defaultOptions()
    );
    
    // 加载 IDL
    const idlPath = path.join(__dirname, '..', 'src', 'idl', 'ignite_contracts.json');
    const idl = JSON.parse(fs.readFileSync(idlPath, 'utf8'));
    
    // 创建程序实例
    const program = new Program(idl, provider);
    
    // 计算工厂 PDA
    const [factoryPda] = PublicKey.findProgramAddressSync(
      [Buffer.from("factory")],
      new PublicKey(PROGRAM_ID)
    );
    
    console.log(`🏭 工厂 PDA: ${factoryPda.toString()}`);
    
    // 检查工厂是否已经存在
    try {
      const factoryAccountInfo = await connection.getAccountInfo(factoryPda);
      if (factoryAccountInfo) {
        console.log('✅ 工厂已经初始化');
        return;
      }
    } catch (error) {
      console.log('📍 工厂尚未初始化，开始初始化...');
    }
    
    // 创建初始化工厂指令
    const initializeFactoryIx = await program.methods
      .initializeFactory()
      .accounts({
        factory: factoryPda,
        authority: authorityKeypair.publicKey,
        systemProgram: SystemProgram.programId,
      })
      .instruction();
    
    const transaction = new Transaction().add(initializeFactoryIx);
    
    // 发送交易
    console.log('📤 发送初始化交易...');
    const signature = await sendAndConfirmTransaction(
      connection,
      transaction,
      [authorityKeypair],
      { commitment: 'confirmed' }
    );
    
    console.log('✅ 工厂初始化成功!');
    console.log(`🔗 交易签名: ${signature}`);
    console.log(`🏭 工厂地址: ${factoryPda.toString()}`);
    console.log(`👤 授权地址: ${authorityKeypair.publicKey.toString()}`);
    
  } catch (error) {
    console.error('❌ 初始化工厂失败:', error);
    if (error.logs) {
      console.error('交易日志:', error.logs);
    }
  }
}

// 直接运行脚本
if (require.main === module) {
  initializeFactory()
    .then(() => {
      console.log('🎉 脚本执行完成');
      process.exit(0);
    })
    .catch((error) => {
      console.error('💥 脚本执行失败:', error);
      process.exit(1);
    });
}

module.exports = { initializeFactory };
